import { MCustomComponentOperation, ModelData } from "@/constants/types";
import { modelService } from "@/modules/model/service";
import { nextTick } from "vue";
import { DiagramCustomizationManagementModel } from "../../DiagramCustomizationManagementModel";
import { CommonNode, commonTreeDataDefault } from "../common/TreeSelectModel";
/* type GroupObj = {
  groupName: string,
  editable: boolean,
  compsList: any[],
  showComps: boolean
}
type ComponentConfig = {
  groupList: GroupObj[]
  rightSelectedIds: string[]
}
 */
type GroupItem = {
  modelId?: string;
  shapeKey?: string;
  operation?: string; // 特殊操作，对于纯图形的元素就是CREATE_SHAPE，其他类型的操作可以后续拓展
  operationParam?: any; // 特殊操作的参数
  dropdownTag?: string; // 下拉标签，用来处理下拉类型的组件菜单， 相同dropdownTag的item会被收起到一个下拉菜单里
};
type SiderbarGroup = {
  id: string;
  cnName: string;
  enName?: string;
  children: GroupItem[];
};

export type SiderbarGroupFront = {
  id: string;
  cnName: string;
  enName?: string;
  editable?: boolean;
  showComps?: boolean;
  children: any[];
  isActive?: boolean;
  originName?: string;
};

type QueryParams = {
  projectId: string;
  modelId: string;
  row: any;
};

interface NewModelData extends ModelData {
  dropdownTag?: string;
  operation?: string;
}
interface NewChildData extends CommonNode {
  dropdownTag?: string;
}

export class ComponentConfigurationModel {
  siderbarConfig: SiderbarGroupFront[] = [];
  rightSelectedIds: string[] = [];
  selectGroupIndex = 0;
  queryParams: QueryParams;
  currentProjectId: string;
  isModelDisabled: boolean;
  currentStep: "groupConfig" | "operationConfig" = "groupConfig";
  currentSelected: any = {};
  operationsOptions: MCustomComponentOperation[] = [];
  dropDownTagOptions: string[] = []; // 当前组件配置下所有分组的dropDownTag集合

  groupNameInputMap = new Map<string, any>();

  constructor(public diagramCustomizationManagementModel: DiagramCustomizationManagementModel) {
    /*   this.stereotypeModelId = query.stereotypeModelId;
    this.constraintModelId = query.constraintModelId; */
    this.queryParams = diagramCustomizationManagementModel.queryParams;
    this.currentProjectId = this.queryParams?.projectId;
    this.isModelDisabled = diagramCustomizationManagementModel.isModelDisabled;
  }

  async initComponentConfigurationrData(siderbarConfig) {
    if (siderbarConfig) {
      const tagList: string[] = [];
      const operationList = await modelService.getOperationsByStId();
      this.siderbarConfig = await Promise.all(
        siderbarConfig.map(async item => {
          return {
            ...item,
            editable: false,
            showComps: true,
            children: await this.fillChildren(item, tagList, operationList)
          };
        })
      );
      this.dropDownTagOptions = [...new Set(tagList)];
    }
  }

  // 组件引用
  async joinSiderbarConfig(siderbarConfigs: SiderbarGroup[]) {
    const tagList: string[] = [];
    const operationList = await modelService.getOperationsByStId();
    for (let siderbarConfig of siderbarConfigs) {
      const existGroup = this.siderbarConfig.find(it => it.cnName === siderbarConfig.cnName);
      // 如果当前分组存在，将children和已有的children合并
      if (existGroup) {
        existGroup.children.push(...(await this.fillChildren(siderbarConfig, tagList, operationList, true, existGroup.children)));
      } else {
        this.siderbarConfig.push({
          ...siderbarConfig,
          editable: false,
          showComps: true,
          children: await this.fillChildren(siderbarConfig, tagList, operationList)
        });
      }
      this.dropDownTagOptions = [...new Set(tagList.concat(this.dropDownTagOptions))];
    }
  }

  async fillChildren(
    siderbarConfig: SiderbarGroup,
    tagList: string[],
    operationList: MCustomComponentOperation[],
    needFilter?: boolean,
    existChildren?: any[]
  ) {
    return Promise.all(
      siderbarConfig.children.map(async child => {
        if (child.modelId) {
          // 这里modelId operation dropdownTag 都相同才认为是同一个
          if (
            needFilter &&
            existChildren &&
            existChildren.find(
              it =>
                it.id === child.modelId &&
                ((!child.operation && !it.operation) || it.operation == child.operation) &&
                ((!child.dropdownTag && !it.dropdownTag) || it.dropdownTag == child.dropdownTag)
            )
          ) {
            return;
          }
          const modelData = await modelService.getModelData(this.currentProjectId, child.modelId);
          const newModelData: NewModelData = { ...modelData };
          if (child.dropdownTag) {
            newModelData.dropdownTag = child.dropdownTag;
            tagList.push(child.dropdownTag);
          }
          if (child.operation) {
            //  配置过操作项，将操作项相应的icon/name/operation进行赋值
            const operationItem = operationList.find(item => item.operation === child.operation);
            if (operationItem) {
              newModelData.operation = operationItem.operation;
              newModelData.icon = operationItem.icon;
              if (newModelData.id === operationItem.classify) {
                newModelData.name = operationItem.operation;
              }
            }
          }
          return newModelData;
        } else if (child.shapeKey) {
          if (needFilter && existChildren && existChildren.find(it => it.shapeKey === child.shapeKey)) {
            return;
          }
          const childData = commonTreeDataDefault[0].children.find(item => item.shapeKey === child.shapeKey);
          if (childData) {
            const newChildData: NewChildData = { ...childData };
            if (child.dropdownTag) {
              newChildData.dropdownTag = child.dropdownTag;
              tagList.push(child.dropdownTag);
            }
            return newChildData;
          }
        }
      })
    ).then(res => res.filter(item => !!item));
  }

  handleStep() {
    if (this.currentStep === "groupConfig") {
      this.currentStep = "operationConfig";
    } else {
      this.currentStep = "groupConfig";
    }
  }

  confirmSelectComp(parentIndex, index) {
    if (index < 0) {
      this.currentSelected = {};
    } else {
      this.currentSelected = this.siderbarConfig[parentIndex].children[index];
    }
  }

  // 获取当前选中组件的可选操作项列表
  async getOperationOptions() {
    if (commonTreeDataDefault[0].children.some(item => item.key === this.currentSelected.key)) return [];
    let options = await modelService.getOperationsByStId(this.currentSelected.id);
    if (!options || !options.length) {
      const stereotypeMetaclass = await modelService.getStereotypeMetaclass(this.currentProjectId, this.currentSelected.id);
      if (stereotypeMetaclass && stereotypeMetaclass[0]) {
        options = await modelService.getOperationsByStId(stereotypeMetaclass[0]);
      }
    }
    this.operationsOptions = options || [];
  }

  // 改变选中operation的值
  async changeOperation(operation: string, parentIndex: number, index: number) {
    if (operation) {
      const operationItem = this.operationsOptions.find(item => item.operation === operation);
      if (operationItem) {
        if (this.siderbarConfig[parentIndex].children[index].id === operationItem.classify) {
          this.siderbarConfig[parentIndex].children[index].name = operationItem.operation;
        }
        this.siderbarConfig[parentIndex].children[index].icon = operationItem.icon;
        this.siderbarConfig[parentIndex].children[index].operation = operationItem.operation;
      }
    } else {
      // 取消掉operation的更改，置换为原始数据
      console.error(this.siderbarConfig[parentIndex].children[index].id);
      const modelData = await modelService.getModelData(this.currentProjectId, this.siderbarConfig[parentIndex].children[index].id);
      this.siderbarConfig[parentIndex].children[index].name = modelData.name;
      this.siderbarConfig[parentIndex].children[index].icon = modelData.icon;
      this.siderbarConfig[parentIndex].children[index].operation = "";
    }
  }
  // 改变选中的标签值
  changeDropDownTag(tag: string, parentIndex: number, index: number) {
    if (tag) {
      this.siderbarConfig[parentIndex].children[index].dropdownTag = tag;
      const isIndex = this.dropDownTagOptions.findIndex(item => item === tag);
      if (isIndex === -1) this.dropDownTagOptions.push(tag);
    } else {
      this.siderbarConfig[parentIndex].children[index].dropdownTag = "";
    }
  }

  async updateGroupName(group: SiderbarGroupFront) {
    if (group.originName === group.cnName) {
      group.editable = false;
    } else {
      const existSameName = this.siderbarConfig.find(it => it.cnName === group.cnName && it !== group);
      if (existSameName) {
        app.$notify({
          title: "提示",
          message: "分组名重复",
          type: "error"
        });
        group.cnName = group.originName as string;
      } else {
        group.enName = group.cnName;
        group.editable = false;
      }
    }
  }

  setGroupInEdit(group: SiderbarGroupFront, event) {
    if (this.isModelDisabled) return;
    group.editable = true;
    group.originName = group.cnName;
    nextTick(() => {
      this.groupNameInputMap.get(group.id)?.focus();
      event.currentTarget.select();
    });
  }
}
